/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.sf.fc.io.ch;

import net.sf.fc.io.event.FileCopyEvent.CopyStatus;
import net.sf.fc.io.event.FileCopyEvent.Level;

import java.io.File;

/**
 *
 * Class that extends {@link RenameFileCopyHelper}. This class can be passed
 * to {@link org.apache.commons.io.FileCopier} to rename files that exist.
 * <p>
 * <tt>RenameAppendFileCopyHelper's</tt> implementation of <tt>handleExistingFile</tt>,
 * takes the existing destination file and appends a String to its name. Then, it
 * tries to rename the existing file on disk and returns the status of the rename
 * attempt.
 *
 * @author David Armstrong
 */
public class RenameAppendFileCopyHelper extends RenameFileCopyHelper {

    private final String append;

    /**
     * Constructor that takes the String which will be appended to the name of
     * existing files that exist.
     */
    public RenameAppendFileCopyHelper(String append) {
        super();
        if(append == null) {
            throw new NullPointerException("Append must not be null");
        }
        this.append = append;
    }

    /**
     * Method that handles destination files that exist during a copy operation.
     * This implementation renames the existing file using the append String
     * that was used to construct the instance of <tt>RenameAppendFileCopyHelper</tt>.
     *
     * @param dest the destination file, which exists.
     * @param source the source file.
     * @return Action.CONTINUE to signal to <tt>FileCopier</tt> to move forward with the
     * copy, Action.ABEND to signal that it should not.
     */
    public Action handleExistingFile(final File source, final File dest) {

        Action action = Action.CONTINUE;

        File newFile = createNewFile(dest);
        boolean renamed = dest.renameTo(newFile);
        if(renamed) {
            reportCopyEvent(source, newFile, CopyStatus.RENAME_COMPLETE, Level.INFO, newFile.length());
        } else {
            reportCopyEvent(source, newFile, CopyStatus.RENAME_FAILED, Level.ERROR, 0);
            action = Action.ABEND;
        }
        return action;
    }

    /**
     * This method renames the destination file using the append String that was
     * passed in the constructor.
     *
     * @param dest
     * @return a File object with the new name. This method does not rename the
     * file itself, only the File object. The <tt>handleExistingFile</tt> method
     * will rename the file on disk.
     */
    public File createNewFile(final File dest) {
        return(new File(dest.getParent(), dest.getName() + append));
    }

     /**
     * This method returns true if subsequent copy operations should be abandoned.
     * Ths method is called by <tt>FileCopier</tt> at the end of each copy operation.
     * This implementation always returns false.
     * @return true if subsequent copy operations should be cancelled.
     */
   public boolean cancel() { return false; }

}
